package vip.xiaonuo.modular.file.util;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.system.SystemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import vip.xiaonuo.modular.file.config.LocalFileConfig;

import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * CommonFileUtils
 *
 * @author JackLee
 * 2022/5/26 10:12
 */
@Slf4j
public class CommonFileUtils {
    public static final String fileRootPath;

    static {
        fileRootPath = SpringUtil.getBean(LocalFileConfig.class).getFileRootPath();
    }


    public static ByteArrayInputStream copyInputStreamAndFileAndReturn(InputStream inputStream, String targetFileName) throws IOException {
        if (!SystemUtil.getOsInfo().isWindows() && targetFileName.contains("\\")) {
            targetFileName = StringUtils.replaceChars(targetFileName, '\\', '/');
        }
        log.info(">>>>>>>>copyInputStreamAndFile: {}", targetFileName);
        File targetFile = new File(targetFileName);
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
        targetFile.createNewFile();

        FileOutputStream outputStream = new FileOutputStream(targetFile);

        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int r;
        while ((r = inputStream.read(buf)) != -1) {
            bao.write(buf, 0, r);
            outputStream.write(buf, 0, r);
        }
        bao.flush();
        outputStream.close();
        return new ByteArrayInputStream(bao.toByteArray());
    }


    public static File copyInputStreamAndReturnFile(InputStream inputStream, String targetFileName) throws IOException {
        if (!SystemUtil.getOsInfo().isWindows() && targetFileName.contains("\\")) {
            targetFileName = StringUtils.replaceChars(targetFileName, '\\', '/');
        }
        log.info(">>>>>>>>copyInputStreamAndFile: {}", targetFileName);
        File targetFile = new File(targetFileName);
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
        FileOutputStream outputStream = null;
        ByteArrayOutputStream bao = null;
        try {
            targetFile.createNewFile();
            outputStream = new FileOutputStream(targetFile);
            bao = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int r;
            while ((r = inputStream.read(buf)) != -1) {
                bao.write(buf, 0, r);
                outputStream.write(buf, 0, r);
            }
        } catch (IOException e) {
            throw new IOException(e);
        } finally {
            if (bao != null) {
                bao.flush();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            inputStream.close();
        }
        return targetFile;
    }


    //删除File对象中抽象的路径方法
    public static void deleteFile(File dir) {

        //将file封装的路径下对象转换为数组
        File[] files = dir.listFiles();

        //判断这个数组为不为空,如果不为空,就执行内部代码
        if (files != null) {

            for (File file : files) {

                //判断是否为文件
                if (file.isFile()) {

                    //如果为文件,执行删除
                    file.delete();

                } else {
                    //如果不为文件,就(递归)进入这个文件夹,删除文件
                    deleteFile(file);
                }
            }

            //删除全部文件后删除空文件夹,最后删除自己
            dir.delete();
        }
    }

    public static void copyFileUsingFileChannels(File source, File dest) throws IOException {
        if (source.exists() && source.isFile()) {
            FileChannel inputChannel = null;
            FileChannel outputChannel = null;
            try {
                inputChannel = new FileInputStream(source).getChannel();
                outputChannel = new FileOutputStream(dest).getChannel();
                outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
            } finally {
                inputChannel.close();
                outputChannel.close();
            }
        }
    }

    public static File getAbsoluteFile(String fileDir, String fileName) {
        File dir = new File(fileDir);
        if (!dir.exists())
            dir.mkdirs();
        return new File(fileDir + File.separator + fileName);
    }

    /**
     * 将ISO_8859_1 格式的编码转换成GBK或者UTF-8
     * @param s
     * @return
     */
    public static String getEncodingString(String s) {
        try {
            //检测编码
            String s1 = new String(s.getBytes(StandardCharsets.ISO_8859_1),"GBK");
            if(Charset.forName("GBK").newEncoder().canEncode(s1)){
                s = s1;
            }else{
                String s2 = new String(s.getBytes(StandardCharsets.ISO_8859_1),"UTF-8");
                if(Charset.forName("UTF-8").newEncoder().canEncode(s1)){
                    s = s2;
                }
            }
            // end
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return s;
    }

    public interface FileType {
        String ZIP = "zip";
        String XLS = "xls";
        String XLSX = "xlsx";
        String CSV = "csv";
    }
}
